// Ofri Keidar 302933981 group 05

package controller;

import java.util.List;
import java.util.Map;

import model.Model;
import model.apartment.*;
import model.database.DBException;

/**
 * This class implements DBController interface. The class performs transactions on system's data, using the database 
 */
public class Transactor implements DBController {
	
	private Model apartmentsManager; // used to manage creating and retrieving apartments
		
	/**
	 * Constructor- creates a new object to manage the transactions
	 * @param apartmentsManager- model object to be used
	 * @throws DBException- throws database exception if could not initialize system
	 */
	public Transactor(Model apartmentsManager) throws DBException {		
		
		// set apartments manager
		this.apartmentsManager = apartmentsManager;
	}

	/**
	 * Gets all vacant flats from the apartments manager.
	 * Flats are sorted by total area in ascending order
	 * Throws database exception if database encountered a problem 
	 */
	@Override
	public List<Flat> getVacantFlats() throws DBException {
		
		// return all vacant flats in system
		return apartmentsManager.getVacantFlats();
	}

	/**
	 * Gets vacant flats with given room number from the apartments manager.
	 * Flats are sorted by total area in ascending order
	 * Throws database exception if database encountered a problem 
	 */
	@Override
	public List<Flat> getVacantFlats(double roomNum) throws DBException {

		// return all vacant flats in system with given room number
		return apartmentsManager.getVacantFlats(roomNum);		
	}
	
	/**
	 * Gets vacant flats with given room number at given address from the apartments manager.
	 * Flats are sorted by total area in ascending order
	 * Throws database exception if database encountered a problem 
	 */
	@Override
	public List<Flat> getVacantFlats(double roomNum, String stName, int bldNumber)
			throws DBException {
		
		// return all vacant flats at given address
		return apartmentsManager.getVacantFlats(roomNum, stName, bldNumber);				
	}

	/**
	 * Gets flats at given address from the apartments manager.
	 * Flats are sorted by total area in ascending order
	 * Throws database exception if database encountered a problem  
	 */
	@Override
	public List<Flat> getFlats(String stName, int bldNumber) throws DBException {

		// return all flats at given address
		return apartmentsManager.getFlats(stName, bldNumber);
	}

	/**
	 * Gets all flats from the apartments manager.
	 * Flats are sorted by total area in ascending order
	 * Throws database exception if database encountered a problem  
	 */
	@Override
	public List<Flat> getFlats() throws DBException {
		
		// return all flats in system
		return apartmentsManager.getAllFlats();
	}
	
	/**
	 * Gets all penthouses from the apartments manager.
	 * Penthouses are sorted by total area in ascending order
	 * Throws database exception if database encountered a problem  
	 */
	@Override
	public List<Penthouse> getPenthouses() throws DBException {
				
		// return all penthouses in system
		return apartmentsManager.getAllPenthouses();
	}

	/**
	 * Gets all garden apartments from the apartments manager.
	 * Garden apartments are sorted by total area in ascending order
	 * Throws database exception if database encountered a problem  
	 */
	@Override
	public List<GardenApartment> getGardenApartments() throws DBException {
		
		// return all garden apartment in system
		return apartmentsManager.getAllGardenAprtmnts();
	}

	/**
	 * Uses the apartments manager to get list of vacant apartments, and returns number of elements in this list.
	 * Throws database exception if database encountered a problem 
	 */
	@Override
	public int getVacantAprtsNum() throws DBException {
		
		// get all vacant apartments in system and return their amount
		return apartmentsManager.getVacantApartments().size();
	}
	
	/**
	 * Uses the apartments manager to get list of vacant apartments at given address, and returns number of elements in this list.
	 * Throws database exception if database encountered a problem 
	 */
	@Override
	public int getVacantAprtsNum(String stName, int bldNumber)
			throws DBException {
		
		// get all vacant apartments at given address and return their amount
		return apartmentsManager.getVacantApartments(stName, bldNumber).size();
	}
	
	/**
	 * Gets parameters of all apartments and new building's address. 
	 * If there already another building at given address, no building is not created and False is returned. 
	 * Otherwise, creates a new building with given details and True is returned.
	 * Throws database exception if database encountered a problem 
	 */
	@Override
	public boolean addBuilding(List<Map<String, String>> parameterList, String stName, int bldNumber) throws DBException {
		
		// check if there is not already another building at given address
		if (apartmentsManager.getBuilding(stName, bldNumber) != null) {
			
			// address is occupied, cannot add a new building there
			return false;
		}
		
		// check that parameters for each apartment are of correct format
		int numOfApartments = parameterList.size();
		boolean parametersCorrect;
		for (int i = 0 ; i < numOfApartments ; ++i) {
			
			// check parameters of current apartment
			parametersCorrect = apartmentsManager.checkApartmentsParameters(parameterList.get(i).get(ParameterParser.TYPE), parameterList.get(i));
			
			// check result
			if (!parametersCorrect) {
				
				// current apartment's parameters are of incorrect format, stop parsing
				return false;
			}
		}
		
		// add new building at given address
		apartmentsManager.addNewBuilding(parameterList, stName, bldNumber);
		return true;
	}
	
	/**
	 * Uses apartments manager to update resident name at apartment with given number at given address.
	 * Returns True if could update, False if not.
	 * Throws database exception if database encountered a problem 
	 */
	@Override
	public boolean updateResident(String stName, int bldNum, int apartmentNum,
			String newResident) throws DBException {

		// update resident name of specified apartment
		return apartmentsManager.updateResident(stName, bldNum, apartmentNum, newResident);
	}
}